package co.edu.usbcali.sgi.presentation.backEndBeans;

import co.edu.usbcali.sgi.exceptions.*;
import co.edu.usbcali.sgi.modelo.*;
import co.edu.usbcali.sgi.modelo.dto.PersonaDTO;
import co.edu.usbcali.sgi.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.sgi.utilities.*;

import com.icesoft.faces.async.render.RenderManager;
import com.icesoft.faces.async.render.Renderable;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.selectinputdate.SelectInputDate;
import com.icesoft.faces.context.DisposableBean;
import com.icesoft.faces.webapp.xmlhttp.FatalRenderingException;
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
import com.icesoft.faces.webapp.xmlhttp.RenderingException;
import com.icesoft.faces.webapp.xmlhttp.TransientRenderingException;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;


/**
*
*
* @author Zathura Code Generator http://code.google.com/p/zathura
*
*/
public class PersonaView extends DataSource implements Renderable,
    DisposableBean {
    private HtmlInputText txtPerCelular;
    private HtmlInputText txtPerCorreo;
    private HtmlInputText txtPerPrimerApellido;
    private HtmlInputText txtPerPrimerNombre;
    private HtmlInputText txtPerSegundoApellido;
    private HtmlInputText txtPerSegundoNombre;
    private HtmlInputText txtPerTelefono;
    private HtmlInputText txtEstCod_Estado;
    private HtmlInputText txtTdocCod_TipoDocumento;
    private HtmlInputText txtPerCedula;
    private HtmlCommandButton btnSave;
    private HtmlCommandButton btnModify;
    private HtmlCommandButton btnDelete;
    private HtmlCommandButton btnClear;
    private boolean renderDataTable;
    private boolean flag = true;
    private RenderManager renderManager;
    private PersistentFacesState state = PersistentFacesState.getInstance();
    private List<Persona> persona;
    private List<PersonaDTO> personaDTO;

    public PersonaView() {
        super("");
    }

    public String action_clear() {
        txtPerCelular.setValue(null);
        txtPerCelular.setDisabled(true);
        txtPerCorreo.setValue(null);
        txtPerCorreo.setDisabled(true);
        txtPerPrimerApellido.setValue(null);
        txtPerPrimerApellido.setDisabled(true);
        txtPerPrimerNombre.setValue(null);
        txtPerPrimerNombre.setDisabled(true);
        txtPerSegundoApellido.setValue(null);
        txtPerSegundoApellido.setDisabled(true);
        txtPerSegundoNombre.setValue(null);
        txtPerSegundoNombre.setDisabled(true);
        txtPerTelefono.setValue(null);
        txtPerTelefono.setDisabled(true);
        txtEstCod_Estado.setValue(null);
        txtEstCod_Estado.setDisabled(true);
        txtTdocCod_TipoDocumento.setValue(null);
        txtTdocCod_TipoDocumento.setDisabled(true);
        txtPerCedula.setValue(null);
        txtPerCedula.setDisabled(false);
        btnSave.setDisabled(true);
        btnDelete.setDisabled(true);
        btnModify.setDisabled(true);
        btnClear.setDisabled(false);

        return "";
    }

    public void listener_txtId(ValueChangeEvent event) {
        if ((event.getNewValue() != null) && !event.getNewValue().equals("")) {
            Persona entity = null;

            try {
                String perCedula = new String(txtPerCedula.getValue().toString());
                entity = BusinessDelegatorView.getPersona(perCedula);
            } catch (Exception e) {
                // TODO: handle exception
            }

            if (entity == null) {
                txtPerCelular.setDisabled(false);
                txtPerCorreo.setDisabled(false);
                txtPerPrimerApellido.setDisabled(false);
                txtPerPrimerNombre.setDisabled(false);
                txtPerSegundoApellido.setDisabled(false);
                txtPerSegundoNombre.setDisabled(false);
                txtPerTelefono.setDisabled(false);
                txtEstCod_Estado.setDisabled(false);
                txtTdocCod_TipoDocumento.setDisabled(false);
                txtPerCedula.setDisabled(false);
                btnSave.setDisabled(false);
                btnDelete.setDisabled(true);
                btnModify.setDisabled(true);
                btnClear.setDisabled(false);
            } else {
                txtPerCelular.setValue(entity.getPerCelular());
                txtPerCelular.setDisabled(false);
                txtPerCorreo.setValue(entity.getPerCorreo());
                txtPerCorreo.setDisabled(false);
                txtPerPrimerApellido.setValue(entity.getPerPrimerApellido());
                txtPerPrimerApellido.setDisabled(false);
                txtPerPrimerNombre.setValue(entity.getPerPrimerNombre());
                txtPerPrimerNombre.setDisabled(false);
                txtPerSegundoApellido.setValue(entity.getPerSegundoApellido());
                txtPerSegundoApellido.setDisabled(false);
                txtPerSegundoNombre.setValue(entity.getPerSegundoNombre());
                txtPerSegundoNombre.setDisabled(false);
                txtPerTelefono.setValue(entity.getPerTelefono());
                txtPerTelefono.setDisabled(false);
                txtEstCod_Estado.setValue(entity.getEstado().getEstCod());
                txtEstCod_Estado.setDisabled(false);
                txtTdocCod_TipoDocumento.setValue(entity.getTipoDocumento()
                                                        .getTdocCod());
                txtTdocCod_TipoDocumento.setDisabled(false);
                txtPerCedula.setValue(entity.getPerCedula());
                txtPerCedula.setDisabled(true);
                btnSave.setDisabled(true);
                btnDelete.setDisabled(false);
                btnModify.setDisabled(false);
                btnClear.setDisabled(false);
            }
        }
    }

    public String action_save() {
        try {
            BusinessDelegatorView.savePersona(FacesUtils.checkString(
                    txtPerCedula), FacesUtils.checkString(txtPerCelular),
                FacesUtils.checkString(txtPerCorreo),
                FacesUtils.checkString(txtPerPrimerApellido),
                FacesUtils.checkString(txtPerPrimerNombre),
                FacesUtils.checkString(txtPerSegundoApellido),
                FacesUtils.checkString(txtPerSegundoNombre),
                FacesUtils.checkString(txtPerTelefono),
                FacesUtils.checkString(txtEstCod_Estado),
                FacesUtils.checkString(txtTdocCod_TipoDocumento));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYSAVED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_delete() {
        try {
            BusinessDelegatorView.deletePersona(FacesUtils.checkString(
                    txtPerCedula));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYDELETED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_modify() {
        try {
            BusinessDelegatorView.updatePersona(FacesUtils.checkString(
                    txtPerCedula), FacesUtils.checkString(txtPerCelular),
                FacesUtils.checkString(txtPerCorreo),
                FacesUtils.checkString(txtPerPrimerApellido),
                FacesUtils.checkString(txtPerPrimerNombre),
                FacesUtils.checkString(txtPerSegundoApellido),
                FacesUtils.checkString(txtPerSegundoNombre),
                FacesUtils.checkString(txtPerTelefono),
                FacesUtils.checkString(txtEstCod_Estado),
                FacesUtils.checkString(txtTdocCod_TipoDocumento));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_modifyWitDTO(String perCedula, String perCelular,
        String perCorreo, String perPrimerApellido, String perPrimerNombre,
        String perSegundoApellido, String perSegundoNombre, String perTelefono,
        String estCod_Estado, String tdocCod_TipoDocumento)
        throws Exception {
        try {
            BusinessDelegatorView.updatePersona(perCedula, perCelular,
                perCorreo, perPrimerApellido, perPrimerNombre,
                perSegundoApellido, perSegundoNombre, perTelefono,
                estCod_Estado, tdocCod_TipoDocumento);
            renderManager.getOnDemandRenderer("PersonaView").requestRender();
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
        } catch (Exception e) {
            //renderManager.getOnDemandRenderer("PersonaView").requestRender();
            FacesUtils.addErrorMessage(e.getMessage());
            throw e;
        }

        return "";
    }

    public List<Persona> getPersona() {
        if (flag) {
            try {
                persona = BusinessDelegatorView.getPersona();
                flag = false;
            } catch (Exception e) {
                flag = true;
                FacesUtils.addErrorMessage(e.getMessage());
            }
        }

        return persona;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setPersona(List<Persona> persona) {
        this.persona = persona;
    }

    public boolean isRenderDataTable() {
        try {
            if (flag) {
                if (BusinessDelegatorView.findTotalNumberPersona() > 0) {
                    renderDataTable = true;
                } else {
                    renderDataTable = false;
                }
            }

            flag = false;
        } catch (Exception e) {
            renderDataTable = false;
            e.printStackTrace();
        }

        return renderDataTable;
    }

    public DataModel getData() {
        state = PersistentFacesState.getInstance();

        if (onePageDataModel == null) {
            onePageDataModel = new LocalDataModel(pageSize);
        }

        return onePageDataModel;
    }

    /**
    * This is where the Object data is retrieved from the database and
    * returned as a list of objects for display in the UI.
    */
    private DataPage<Persona> getDataPage(int startRow, int pageSize) {
        // Retrieve the total number of objects from the database.  This
        // number is required by the DataPage object so the paginator will know
        // the relative location of the page data.
        int totalNumberPersona = 0;

        try {
            totalNumberPersona = BusinessDelegatorView.findTotalNumberPersona()
                                                      .intValue();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Calculate indices to be displayed in the ui.
        int endIndex = startRow + pageSize;

        if (endIndex > totalNumberPersona) {
            endIndex = totalNumberPersona;
        }

        try {
            persona = BusinessDelegatorView.findPagePersona(sortColumnName,
                    sortAscending, startRow, endIndex - startRow);

            // Remove this Renderable from the existing render groups.
            //leaveRenderGroups();        			
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Add this Renderable to the new render groups.
        //joinRenderGroups();
        // Reset the dirtyData flag.
        onePageDataModel.setDirtyData(false);
        // This is required when using Hibernate.  If the SessionManager is not
        // cleared or closed objects are cached and stale objects will show up
        // in the table.
        // This way, the detached objects are reread from the database.
        // This call is not required with Hibernate, which uses a Query Hint
        // to clear the l2 cache in the DAO.
        flag = true;

        return new DataPage<Persona>(totalNumberPersona, startRow, persona);
    }

    public DataModel getDataDTO() {
        state = PersistentFacesState.getInstance();

        if (onePageDataModel == null) {
            onePageDataModel = new LocalDataModelDTO(pageSize);
        }

        return onePageDataModel;
    }

    /**
    * This is where the Object data is retrieved from the database and
    * returned as a list of objects for display in the UI.
    */
    private DataPage<PersonaDTO> getDataPageDTO(int startRow, int pageSize) {
        // Retrieve the total number of objects from the database.  This
        // number is required by the DataPage object so the paginator will know
        // the relative location of the page data.
        int totalNumberPersona = 0;

        try {
            totalNumberPersona = BusinessDelegatorView.findTotalNumberPersona()
                                                      .intValue();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Calculate indices to be displayed in the ui.
        int endIndex = startRow + pageSize;

        if (endIndex > totalNumberPersona) {
            endIndex = totalNumberPersona;
        }

        try {
            persona = BusinessDelegatorView.findPagePersona(sortColumnName,
                    sortAscending, startRow, endIndex - startRow);

            if (Utilities.validationsList(persona)) {
                personaDTO = new ArrayList<PersonaDTO>();

                for (Persona personaTmp : persona) {
                    PersonaDTO personaDTO2 = new PersonaDTO();
                    personaDTO2.setPerCedula(personaTmp.getPerCedula().toString());
                    personaDTO2.setPerCelular((personaTmp.getPerCelular() != null)
                        ? personaTmp.getPerCelular().toString() : null);
                    personaDTO2.setPerCorreo((personaTmp.getPerCorreo() != null)
                        ? personaTmp.getPerCorreo().toString() : null);
                    personaDTO2.setPerPrimerApellido((personaTmp.getPerPrimerApellido() != null)
                        ? personaTmp.getPerPrimerApellido().toString() : null);
                    personaDTO2.setPerPrimerNombre((personaTmp.getPerPrimerNombre() != null)
                        ? personaTmp.getPerPrimerNombre().toString() : null);
                    personaDTO2.setPerSegundoApellido((personaTmp.getPerSegundoApellido() != null)
                        ? personaTmp.getPerSegundoApellido().toString() : null);
                    personaDTO2.setPerSegundoNombre((personaTmp.getPerSegundoNombre() != null)
                        ? personaTmp.getPerSegundoNombre().toString() : null);
                    personaDTO2.setPerTelefono((personaTmp.getPerTelefono() != null)
                        ? personaTmp.getPerTelefono().toString() : null);
                    personaDTO2.setEstCod_Estado((personaTmp.getEstado()
                                                            .getEstCod() != null)
                        ? personaTmp.getEstado().getEstCod().toString() : null);
                    personaDTO2.setTdocCod_TipoDocumento((personaTmp.getTipoDocumento()
                                                                    .getTdocCod() != null)
                        ? personaTmp.getTipoDocumento().getTdocCod().toString()
                        : null);
                    personaDTO2.setPersona(personaTmp);
                    personaDTO2.setPersonaView(this);
                    personaDTO.add(personaDTO2);
                }
            }

            // Remove this Renderable from the existing render groups.
            leaveRenderGroups();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Add this Renderable to the new render groups.
        joinRenderGroups();
        // Reset the dirtyData flag.
        onePageDataModel.setDirtyData(false);
        // This is required when using Hibernate.  If the SessionManager is not
        // cleared or closed objects are cached and stale objects will show up
        // in the table.
        // This way, the detached objects are reread from the database.
        // This call is not required with Hibernate, which uses a Query Hint
        // to clear the l2 cache in the DAO.
        flag = true;

        return new DataPage<PersonaDTO>(totalNumberPersona, startRow, personaDTO);
    }

    protected boolean isDefaultAscending(String sortColumn) {
        return true;
    }

    /**
    * This method is called when a render call is made from the server. Render
    * calls are only made to views containing an updated record. The data is
    * marked as dirty to trigger a fetch of the updated record from the
    * database before rendering takes place.
    */
    public PersistentFacesState getState() {
        onePageDataModel.setDirtyData();

        return state;
    }

    /**
    * This method is called from faces-config.xml with each new session.
    */
    public void setRenderManager(RenderManager renderManager) {
        this.renderManager = renderManager;
    }

    public void renderingException(RenderingException arg0) {
        if (arg0 instanceof TransientRenderingException) {
        } else if (arg0 instanceof FatalRenderingException) {
            // Remove from existing Customer render groups.
            leaveRenderGroups();
        }
    }

    /**
    * Remove this Renderable from existing uiCustomerBeans render groups.
    * OnDemandRenderers are named/created using the underlying Customer Number.
    */
    private void leaveRenderGroups() {
        if (Utilities.validationsList(personaDTO)) {
            for (PersonaDTO personaTmp : personaDTO) {
                renderManager.getOnDemandRenderer("PersonaView").remove(this);
            }
        }
    }

    /**
    * Add this Renderable to the new uiCustomerBeans render groups.
    * OnDemandRenderers are named/created using the underlying Customer Number.
    */
    private void joinRenderGroups() {
        if (Utilities.validationsList(personaDTO)) {
            for (PersonaDTO personaTmp : personaDTO) {
                renderManager.getOnDemandRenderer("PersonaView").add(this);
            }
        }
    }

    public void dispose() throws Exception {
    }

    public RenderManager getRenderManager() {
        return renderManager;
    }

    public void setState(PersistentFacesState state) {
        this.state = state;
    }

    public HtmlInputText getTxtPerCelular() {
        return txtPerCelular;
    }

    public void setTxtPerCelular(HtmlInputText txtPerCelular) {
        this.txtPerCelular = txtPerCelular;
    }

    public HtmlInputText getTxtPerCorreo() {
        return txtPerCorreo;
    }

    public void setTxtPerCorreo(HtmlInputText txtPerCorreo) {
        this.txtPerCorreo = txtPerCorreo;
    }

    public HtmlInputText getTxtPerPrimerApellido() {
        return txtPerPrimerApellido;
    }

    public void setTxtPerPrimerApellido(HtmlInputText txtPerPrimerApellido) {
        this.txtPerPrimerApellido = txtPerPrimerApellido;
    }

    public HtmlInputText getTxtPerPrimerNombre() {
        return txtPerPrimerNombre;
    }

    public void setTxtPerPrimerNombre(HtmlInputText txtPerPrimerNombre) {
        this.txtPerPrimerNombre = txtPerPrimerNombre;
    }

    public HtmlInputText getTxtPerSegundoApellido() {
        return txtPerSegundoApellido;
    }

    public void setTxtPerSegundoApellido(HtmlInputText txtPerSegundoApellido) {
        this.txtPerSegundoApellido = txtPerSegundoApellido;
    }

    public HtmlInputText getTxtPerSegundoNombre() {
        return txtPerSegundoNombre;
    }

    public void setTxtPerSegundoNombre(HtmlInputText txtPerSegundoNombre) {
        this.txtPerSegundoNombre = txtPerSegundoNombre;
    }

    public HtmlInputText getTxtPerTelefono() {
        return txtPerTelefono;
    }

    public void setTxtPerTelefono(HtmlInputText txtPerTelefono) {
        this.txtPerTelefono = txtPerTelefono;
    }

    public HtmlInputText getTxtEstCod_Estado() {
        return txtEstCod_Estado;
    }

    public void setTxtEstCod_Estado(HtmlInputText txtEstCod_Estado) {
        this.txtEstCod_Estado = txtEstCod_Estado;
    }

    public HtmlInputText getTxtTdocCod_TipoDocumento() {
        return txtTdocCod_TipoDocumento;
    }

    public void setTxtTdocCod_TipoDocumento(
        HtmlInputText txtTdocCod_TipoDocumento) {
        this.txtTdocCod_TipoDocumento = txtTdocCod_TipoDocumento;
    }

    public HtmlInputText getTxtPerCedula() {
        return txtPerCedula;
    }

    public void setTxtPerCedula(HtmlInputText txtPerCedula) {
        this.txtPerCedula = txtPerCedula;
    }

    public HtmlCommandButton getBtnSave() {
        return btnSave;
    }

    public void setBtnSave(HtmlCommandButton btnSave) {
        this.btnSave = btnSave;
    }

    public HtmlCommandButton getBtnModify() {
        return btnModify;
    }

    public void setBtnModify(HtmlCommandButton btnModify) {
        this.btnModify = btnModify;
    }

    public HtmlCommandButton getBtnDelete() {
        return btnDelete;
    }

    public void setBtnDelete(HtmlCommandButton btnDelete) {
        this.btnDelete = btnDelete;
    }

    public HtmlCommandButton getBtnClear() {
        return btnClear;
    }

    public void setBtnClear(HtmlCommandButton btnClear) {
        this.btnClear = btnClear;
    }

    public void setRenderDataTable(boolean renderDataTable) {
        this.renderDataTable = renderDataTable;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public List<PersonaDTO> getPersonaDTO() {
        return personaDTO;
    }

    public void setPersonaDTO(List<PersonaDTO> personaDTO) {
        this.personaDTO = personaDTO;
    }

    public TimeZone getTimeZone() {
        return java.util.TimeZone.getDefault();
    }

    /**
    * A special type of JSF DataModel to allow a datatable and datapaginator
    * to page through a large set of data without having to hold the entire
    * set of data in memory at once.
    * Any time a managed bean wants to avoid holding an entire dataset,
    * the managed bean declares this inner class which extends PagedListDataModel
    * and implements the fetchData method. fetchData is called
    * as needed when the table requires data that isn't available in the
    * current data page held by this object.
    * This requires the managed bean (and in general the business
    * method that the managed bean uses) to provide the data wrapped in
    * a DataPage object that provides info on the full size of the dataset.
    */
    private class LocalDataModel extends PagedListDataModel {
        public LocalDataModel(int pageSize) {
            super(pageSize);
        }

        public DataPage<Persona> fetchPage(int startRow, int pageSize) {
            // call enclosing managed bean method to fetch the data
            return getDataPage(startRow, pageSize);
        }
    }

    private class LocalDataModelDTO extends PagedListDataModel {
        public LocalDataModelDTO(int pageSize) {
            super(pageSize);
        }

        public DataPage<PersonaDTO> fetchPage(int startRow, int pageSize) {
            // call enclosing managed bean method to fetch the data
            return getDataPageDTO(startRow, pageSize);
        }
    }
}
